// 项目入口文件

// 加载模块
const express = require('express')
const path = require('path')
const usersRouter = require('./routers/usersRouter.js')
const goodsRouter = require('./routers/goodsRouter.js')
const cors = require('cors')

// 创建express实例
const app = express()

/* // 使用 cookie-parser 插件来解析cookie数据
// 安装: npm i cookie-parser
// 加载模块
let cookieParser = require('cookie-parser')
// 使用cookieParser插件
app.use(cookieParser())
// 使用cookieParser插件之后: 
// 1.在req请求对象上添加了一个cookies属性(用于获取客户端的cookie数据)
// 2.在res响应对象上有一个cookie方法(用于设置客户端的cookie数据) */


/* // session会话控制
// http协议是无状态的，当前请求和上一次请求没有对应关系
// 在web应用中cookie是一种记录用户状态的机制
// 在web应用中session是一种记录用户状态的机制
// cookie存储在浏览器，session存储在服务器
// 使用 express-session 插件来操作session
// 安装：npm i express-session
// 加载模块
let session = require('express-session')
//  使用插件
app.use(session({// session的配置项
    secret: 'hehehaha',// 加密口令
    resave: true,// 重新保存session
    saveUninitialized: false,// 是否保存未初始化的session，默认为true
    name: 'nicai',// cookie名称，默认为 'connect.sid'
    cookie: {
        maxAge: 1000*60*30,// cookie的有效期，毫秒
        domain: 'localhost',// cookie的域名
        path: '/'// cookie的路径
    }
}))
// 使用插件之后：
// session = session id + session data
// 1.session的一部分叫session id，通过cookie存储在浏览器
// 2.session的另一部分叫session data，存储在服务器（内存或数据库）
// 3.再次访问服务时，插件根据前端携带的session id自动匹配到对应的session data，然后将session data添加到req对象的session属性{session data} */

// 保持登录状态：session 或 token

// 使用 session 实现
// 1.使用session时，需要用到cookie，cookie不能跨域使用
// 2.session data需要存储在服务器（内存或数据库）

// 使用 token 实现
// token 是象征、标志的意思
// 在计算机身份认证中通常叫做令牌
// 通俗讲就是一种'暗号'

// token的优点：
// 1.可以跨域使用
// 2.不需要存储在服务器中（不需要存储空间）
// 3.对于单点登录更友好
// 4.更适合在移动端使用

// JWT -> Json Web Token
// JWT是一种token的具体实现方式
// 官网：https://jwt.io

// JWT是一种三段式加密字符串
// 如 'aaaaaaaa.bbbbbbbb.cccccccc'

// 第一段：header头信息，是一个json对象，使用base64编码
// header = {
//     "alg": "HS256",// 算法
//     "typ": "JWT"// JWT类型的token
// }
// base64(header) => 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9'

// 第二段：payload有效载荷，是一个json对象，使用base64编码
// payload = {
//     "sub": "1234567890",// 主题
//     "name": "John Doe",// 创建者名称
//     "iat": 1516239022,// 发布时间
//     "exp": 30,// 有效期，秒

//     // 除了上面的默认配置之外，通常还会在payload中存储用户信息（不要放敏感信息）
//     "user": "xiaocuo",// 用户账号
//     "nick": "小错",// 用户昵称
// }
// base64(payload) => 'eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ'

// 第三段：signature签名，使用base64编码之后的header和payload，再加上加密口令，使用 HS256 加密算法进行加密生成签名
// HS256(base64(header)+'.'+base64(payload),secret口令) => '6K09PJU3kWx18qUcqQNvG3R_ozSm9RZRuBzeb7Tnl5o'

// JWT生成的token：'第一段.第二段.第三段'

/* // 在nodejs中使用JWT
// 安装：npm i jsonwebtoken
// 加载模块
const jwt = require('jsonwebtoken')
// 生成token
// let token = jwt.sign(payload1,secret,payload2)
// payload1 是一个json对象，通常是要存储的用户信息
// secret 加密口令
// payload2 是一个json对象，用于其他设置（有效期，发布时间，主题等等）
let info = {// 用户信息
    "user":"xiaocuo",
    "nickname": "小错",
    "email": "2239222721@qq.com",
    "age": "18",
    "sex": "男"
}
// expiresIn有效期，单位是秒，可以设置 '1d'1天  '3d'3天
let token = jwt.sign(info,'hehe123',{"expiresIn":3})
// console.log( token )// 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoieGlhb2N1byIsIm5pY2tuYW1lIjoi5bCP6ZSZIiwiZW1haWwiOiIyMjM5MjIyNzIxQHFxLmNvbSIsImFnZSI6IjE4Iiwic2V4Ijoi55S3IiwiaWF0IjoxNjcxNDE3Njk3LCJleHAiOjE2NzE0MTc3MDB9.Sbj6xdsP4UInUGF3FFwPWpX5kW2aDD1-mZUl2fglrrs' */

/* setTimeout(()=>{
    // 验证token
    // jwt.verify(token,secret,callback)
    // token 要验证的token字符串
    // secret 加密口令
    // callback 验证完成执行的回调函数
    jwt.verify(token,'hehe123',(err,payload)=>{
        // err 错误对象
        // payload token中存储的用户信息
        if (err) {// token验证失败
            console.log( '验证失败1',err )// token过期了
        } else {// token验证成功
            console.log( '验证成功1',payload )
        }
    })
},4000) */

/* setTimeout(()=>{
    // 验证token
    // jwt.verify(token,secret,callback)
    // token 要验证的token字符串
    // secret 加密口令
    // callback 验证完成执行的回调函数
    jwt.verify(token,'hehe124',(err,payload)=>{
        // err 错误对象
        // payload token中存储的用户信息
        if (err) {// token验证失败
            console.log( '验证失败2',err )// 无效的签名
        } else {// token验证成功
            console.log( '验证成功2',payload )
        }
    })
},2000) */

/* setTimeout(()=>{
    // 验证token
    // jwt.verify(token,secret,callback)
    // token 要验证的token字符串
    // secret 加密口令
    // callback 验证完成执行的回调函数
    jwt.verify(token+'asd','hehe123',(err,payload)=>{
        // err 错误对象
        // payload token中存储的用户信息
        if (err) {// token验证失败
            console.log( '验证失败3',err )// 无效的签名
        } else {// token验证成功
            console.log( '验证成功3',payload )
        }
    })
},2000) */

/* setTimeout(()=>{
    // 验证token
    // jwt.verify(token,secret,callback)
    // token 要验证的token字符串
    // secret 加密口令
    // callback 验证完成执行的回调函数
    jwt.verify(token,'hehe123',(err,payload)=>{
        // err 错误对象
        // payload token中存储的用户信息
        if (err) {// token验证失败
            console.log( '验证失败4',err )
        } else {// token验证成功
            console.log( '验证成功4',payload )
            // payload = {
            //     user: 'xiaocuo',
            //     nickname: '小错',
            //     email: '2239222721@qq.com',
            //     age: '18',
            //     sex: '男',
            //     iat: 1671418536,
            //     exp: 1671418539
            // }
        }
    })
},2000) */


// 设置cors跨域资源共享
app.use(cors())

// 连接数据库
require('./db/connect.js')

// 解析请求体中的x-www-form-urlencoded数据
app.use(express.urlencoded({extended:false}))

// 解析请求体中的json数据
app.use(express.json())

// 使用路由表去匹配用户请求
app.use('/users',usersRouter)
app.use('/goods',goodsRouter)

// 设置静态资源目录www
app.use('/static',express.static(path.join(__dirname,'www')))

// 监听端口
app.listen(8080,()=>{
    console.log( '---------服务启动成功---------' )
})
